package com.yeban.javase.day20.reflect.singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * @Desc 线程安全的单例模式  DCL
 * @Author yeban
 * @Date 2025/11/4
 *
 * 反射获取私有的构造方法，进行实例创建，与当前getInstance()获取的实例不是同一个
 */
public class SingletonDemoTest {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        SingletonDemo2 s1 = SingletonDemo2.getInstance();
        SingletonDemo2 s2 = SingletonDemo2.getInstance();
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s1 == s2);   // true

        /*// 通过反射获取私有构造器
        // 获取类类型，并获取对应的私有构造方法
        Class<SingletonDemo2> clazz = SingletonDemo2.class;
        Constructor<SingletonDemo2> constructor = clazz.getDeclaredConstructor();
        // 取消访问权限检查
        constructor.setAccessible(true);
        // 创建实例
        SingletonDemo2 s3 = constructor.newInstance();
        System.out.println(s3);
        System.out.println(s2 == s3);   // false*/

        // 通过反射获取私有构造器
        // 获取类类型，并获取对应的私有构造方法
        Class<SingletonDemo3> clazz = SingletonDemo3.class;
        Constructor<SingletonDemo3> constructor = clazz.getDeclaredConstructor();
        // 取消访问权限检查
        constructor.setAccessible(true);
        // 创建实例
        SingletonDemo3 s3 = constructor.newInstance();

        // 通过改变得到adas属性，再将其改变成false
        Field field = clazz.getDeclaredField("adas");
        field.setAccessible(true);
        field.set(s3, false);

        SingletonDemo3 s4 = constructor.newInstance();
        System.out.println(s4);
        System.out.println(s3 == s4);
    }
}
